# BigData course project
# Serial version of training algorithm for SOM
# Sparse vector implementation 
#

import sys
import util
from util import log

class SparseVec:
    # we know how to build ourselves from a string with 
    # following syntax:
    # <index1> <value1> <index2> <value2> ... <indexN> <valueN>    
    #
    # where is at most the dimension for this vector.
    # Purpose is to buidl a map of index -> value, indicating the 
    # non zero entries of vector 
    #
    def __init__(self, n, s):
        self.cells = dict()
        toks = s.split()
        for i in xrange(0,len(toks),2):
            try:
                self.cells[int(toks[i])] = float(toks[i+1])
            except:
                log("Failed to parse sparse vector spec %s at %i: %s\n", 
                    s, i, sys.exc_info())
                raise
        if len(self.cells) > n:
            log("Sparse vector spec(%s) has more elements than dim %d\n",
                s, n)
            raise
        
    # getter method to retrieve i-th value of vector
    def __getitem__(self, i):
        try:
            v = self.cells[i]
        except KeyError:
            v = 0
        return v

    # knows how to dump back into an string
    def dump(self):
        dump_tup = lambda t: "%d %2.6f" % t
        fst = lambda t: t[0]
        return " ".join(sorted(map(dump_tup, self.cells.items()), key=fst))
